package com.papercutting.platform.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.papercutting.platform.dto.query.UserQuery;
import com.papercutting.platform.dto.request.UserCreateRequest;
import com.papercutting.platform.dto.request.UserUpdateRequest;
import com.papercutting.platform.dto.response.PageResult;
import com.papercutting.platform.dto.response.UserResponse;
import com.papercutting.platform.entity.User;
import com.papercutting.platform.mapper.UserMapper;
import com.papercutting.platform.service.UserService;
import com.papercutting.platform.util.EntityConverter;
import com.papercutting.platform.util.PasswordUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
    
    private final UserMapper userMapper;
    
    @Override
    @Transactional
    public Long createUser(UserCreateRequest request) {
        log.info("创建用户: {}", request.getNickname());
        
        // 检查用户名、手机号、邮箱是否已存在
        if (existsByNickname(request.getNickname())) {
            throw new RuntimeException("用户名已存在");
        }
        if (StringUtils.hasText(request.getPhone()) && existsByPhone(request.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }
        if (StringUtils.hasText(request.getEmail()) && existsByEmail(request.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }
        
        User user = EntityConverter.toUser(request);
        userMapper.insert(user);
        
        log.info("用户创建成功，ID: {}", user.getId());
        return user.getId();
    }
    
    @Override
    @Transactional
    public void updateUser(UserUpdateRequest request) {
        log.info("更新用户: {}", request.getId());
        
        User existingUser = userMapper.selectById(request.getId());
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 检查用户名、手机号、邮箱是否重复（排除当前用户）
        if (StringUtils.hasText(request.getNickname())) {
            User user = userMapper.selectByNickname(request.getNickname());
            if (user != null && !user.getId().equals(request.getId())) {
                throw new RuntimeException("用户名已存在");
            }
        }
        if (StringUtils.hasText(request.getPhone())) {
            User user = userMapper.selectByPhone(request.getPhone());
            if (user != null && !user.getId().equals(request.getId())) {
                throw new RuntimeException("手机号已存在");
            }
        }
        if (StringUtils.hasText(request.getEmail())) {
            User user = userMapper.selectByEmail(request.getEmail());
            if (user != null && !user.getId().equals(request.getId())) {
                throw new RuntimeException("邮箱已存在");
            }
        }
        
        EntityConverter.updateUser(existingUser, request);
        userMapper.updateById(existingUser);
        
        log.info("用户更新成功，ID: {}", request.getId());
    }
    
    @Override
    @Transactional
    public void deleteUser(Long id) {
        log.info("删除用户: {}", id);

        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 使用MyBatis Plus的逻辑删除
        userMapper.deleteById(id);

        log.info("用户删除成功，ID: {}", id);
    }
    
    @Override
    @Transactional
    public void batchDeleteUsers(List<Long> userIds) {
        log.info("批量删除用户: {}", userIds);
        
        for (Long userId : userIds) {
            deleteUser(userId);
        }
        
        log.info("批量删除用户成功，数量: {}", userIds.size());
    }
    
    @Override
    public UserResponse getUserById(Long id) {
        User user = userMapper.selectById(id);
        if (user == null || user.getDeleted()) {
            return null;
        }
        return EntityConverter.toUserResponse(user);
    }
    
    @Override
    public PageResult<UserResponse> getUserPage(UserQuery query) {
        Page<User> page = new Page<>(query.getPage(), query.getSize());
        IPage<User> userPage = userMapper.selectUserPage(page, query);
        
        List<UserResponse> userResponses = EntityConverter.toUserResponseList(userPage.getRecords());
        
        return PageResult.of(userResponses, userPage.getTotal(), query.getPage(), query.getSize());
    }
    
    @Override
    public List<UserResponse> getUserList(UserQuery query) {
        List<User> users = userMapper.selectUserList(query);
        return EntityConverter.toUserResponseList(users);
    }
    
    @Override
    @Transactional
    public void updateUserStatus(Long id, Integer status) {
        log.info("更新用户状态: {} -> {}", id, status);
        
        User user = userMapper.selectById(id);
        if (user == null || user.getDeleted()) {
            throw new RuntimeException("用户不存在");
        }
        
        user.setStatus(status);
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);
        
        log.info("用户状态更新成功，ID: {}", id);
    }
    
    @Override
    @Transactional
    public void batchUpdateUserStatus(List<Long> userIds, Integer status) {
        log.info("批量更新用户状态: {} -> {}", userIds, status);
        
        int count = userMapper.batchUpdateStatus(userIds, status);
        
        log.info("批量更新用户状态成功，数量: {}", count);
    }
    
    @Override
    @Transactional
    public void resetPassword(Long id, String newPassword) {
        log.info("重置用户密码: {}", id);
        
        User user = userMapper.selectById(id);
        if (user == null || user.getDeleted()) {
            throw new RuntimeException("用户不存在");
        }
        
        user.setPassword(PasswordUtil.encode(newPassword));
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);
        
        log.info("用户密码重置成功，ID: {}", id);
    }
    
    @Override
    public UserResponse authenticate(String username, String password) {
        User user = userMapper.selectByNickname(username);
        if (user == null || user.getDeleted() || user.getStatus() != 0) {
            return null;
        }
        
        if (!PasswordUtil.matches(password, user.getPassword())) {
            return null;
        }
        
        // 更新最后登录时间
        user.setLastLoginTime(LocalDateTime.now());
        userMapper.updateById(user);
        
        return EntityConverter.toUserResponse(user);
    }
    
    @Override
    public User findByOpenId(String openId) {
        return userMapper.selectList(null).stream()
                .filter(user -> openId.equals(user.getOpenId()) && !user.getDeleted())
                .findFirst()
                .orElse(null);
    }
    
    @Override
    public User findByPhone(String phone) {
        return userMapper.selectByPhone(phone);
    }
    
    @Override
    public User findByEmail(String email) {
        return userMapper.selectByEmail(email);
    }
    
    @Override
    public boolean existsByNickname(String nickname) {
        return userMapper.selectByNickname(nickname) != null;
    }
    
    @Override
    public boolean existsByPhone(String phone) {
        return userMapper.selectByPhone(phone) != null;
    }
    
    @Override
    public boolean existsByEmail(String email) {
        return userMapper.selectByEmail(email) != null;
    }
    
    @Override
    public Map<String, Object> getUserStats() {
        Map<String, Object> stats = new HashMap<>();
        
        // 总用户数
        UserQuery totalQuery = new UserQuery();
        Long totalCount = userMapper.countUsers(totalQuery);
        stats.put("totalCount", totalCount);
        
        // 正常用户数
        UserQuery normalQuery = new UserQuery();
        normalQuery.setStatus(0);
        Long normalCount = userMapper.countUsers(normalQuery);
        stats.put("normalCount", normalCount);
        
        // 禁用用户数
        UserQuery disabledQuery = new UserQuery();
        disabledQuery.setStatus(1);
        Long disabledCount = userMapper.countUsers(disabledQuery);
        stats.put("disabledCount", disabledCount);
        
        // 管理员用户数
        UserQuery adminQuery = new UserQuery();
        adminQuery.setUserType(1);
        Long adminCount = userMapper.countUsers(adminQuery);
        stats.put("adminCount", adminCount);
        
        return stats;
    }
    
    @Override
    public Long getUserCount() {
        UserQuery query = new UserQuery();
        return userMapper.countUsers(query);
    }
    
    @Override
    public User findByNickname(String nickname) {
        return userMapper.selectByNickname(nickname);
    }
    
    @Override
    public User findById(Long id) {
        return userMapper.selectById(id);
    }
    
    @Override
    @Transactional
    public User save(User user) {
        if (user.getId() == null) {
            // 新增
            if (user.getCreateTime() == null) {
                user.setCreateTime(LocalDateTime.now());
            }
            user.setUpdateTime(LocalDateTime.now());
            userMapper.insert(user);
        } else {
            // 更新
            user.setUpdateTime(LocalDateTime.now());
            userMapper.updateById(user);
        }
        return user;
    }
    
    @Override
    @Transactional
    public void deleteById(Long id) {
        userMapper.deleteById(id);
    }
    
    @Override
    public org.springframework.data.domain.Page<User> findUserList(String keyword, Integer userType, Pageable pageable) {
        UserQuery query = new UserQuery();
        query.setKeyword(keyword);
        query.setUserType(userType);
        query.setPage((int) pageable.getPageNumber() + 1);
        query.setSize((int) pageable.getPageSize());
        
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<User> mybatisPage = 
            new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(query.getPage(), query.getSize());
        
        IPage<User> result = userMapper.selectUserPage(mybatisPage, query);
        
        return new PageImpl<>(result.getRecords(), pageable, result.getTotal());
    }
}